package com.yingxin.yxerp.module.print.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yingxin.yx.framework.commons.activiti.ApprovalStatus;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yx.framework.commons.helper.DateHelper;
import com.yingxin.yx.framework.user.core.IUserSupport;
import com.yingxin.yxerp.module.common.BusinessTypeHelper;
import com.yingxin.yxerp.module.oplog.aop.OplogAnnotation;
import com.yingxin.yxerp.module.print.constant.PrintLimitTypeConst;
import com.yingxin.yxerp.module.print.constant.PrintStatusConst;
import com.yingxin.yxerp.module.print.entity.PrintApply;
import com.yingxin.yxerp.module.print.entity.PrintBusinessStat;
import com.yingxin.yxerp.module.print.entity.PrintLimit;
import com.yingxin.yxerp.module.print.mapper.PrintApplyMapper;
import com.yingxin.yxerp.module.print.service.IPrintApplyService;
import com.yingxin.yxerp.module.print.service.IPrintBusinessStatService;
import com.yingxin.yxerp.module.print.service.IPrintLimitService;
import com.yingxin.yxerp.module.print.service.process.PrintApplyProcessHandler;
import com.yingxin.yxerp.module.print.vo.resp.PrintApplyRespVo;
import com.yingxin.yxerp.module.sys.service.IActivitiCoreInformationService;
import com.yingxin.yxerp.module.sys.service.IBusinessTypeSettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 打印申请 服务实现类
 * @author fanchao
 * @since 2022-03-21
 */

@Service
public class PrintApplyServiceImpl
        extends ServiceImpl<PrintApplyMapper, PrintApply>
        implements IPrintApplyService {

    @Autowired
    private IUserSupport userSupport;

    @Autowired
    private IPrintBusinessStatService printBusinessStatService;

    @Autowired
    private IPrintLimitService printLimitService;

    @Autowired
    private PrintApplyProcessHandler printApplyProcessHandler;

    @Autowired
    private IBusinessTypeSettingService businessTypeSettingService;

    @Autowired
    private IActivitiCoreInformationService activitiCoreInformationService;

    /**
     * 根据 id 查询
     */
    @Override
    public PrintApplyRespVo getVo( String id ){
        PrintApplyRespVo vo = baseMapper.getVo( id );
        vo.setCreateTimeFormat( DateHelper.dateFormat( vo.getCreateTime(), DateHelper.YYYYMMDDHHMMSS ) );
        vo.setBusinessTypeName( BusinessTypeHelper.getName( vo.getBusinessType() ) );
        vo.setLastPrintTimeFormat( DateHelper.dateFormat( vo.getLastPrintTime(), DateHelper.YYYYMMDDHHMMSS ) );
        return vo;
    }

    /**
     * 创建
     */
    @OplogAnnotation(biz = BusinessType.DYSQ, id = "{{apply.id}}", action = "新增",
            desc = "申请单号[{{apply.applyNo}}]，业务单号[{{apply.businessNo}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void create(PrintApply apply) {
        PrintLimit printLimit = printLimitService.getById(apply.getBusinessType());
        if (printLimit != null) {
            if (PrintLimitTypeConst.LIMIT_N.equals(printLimit.getLimitType())) {
                throw new BizException("打印被禁止");
            }
        }
        PrintBusinessStat printBusiness = printBusinessStatService.getById(apply.getBusinessId());
        if (printBusiness == null) {
            throw new BizException("当前状态为可打印，请直接打印");
        }
        if (PrintStatusConst.PRINTABLE.equals(printBusiness.getPrintStatus())) {
            throw new BizException("当前状态为可打印，请直接打印");
        }
        if (PrintStatusConst.AFTER_APPROVED.equals(printBusiness.getPrintStatus())) {
            throw new BizException("审核后可打印");
        }
        // 查询是否已经申请
        PrintApply inApply = getInApply(apply.getBusinessId(), apply.getBusinessType(), userSupport.getUserId());
        if (inApply != null) {
            throw new BizException("正在申请中");
        }
        PrintApply waitingPrint = getWaitingPrintApply(apply.getBusinessId(), apply.getBusinessType(), userSupport.getUserId());
        if (waitingPrint != null) {
            throw new BizException("已申请通过，待打印");
        }
        apply.setApplyNo(businessTypeSettingService.next(BusinessType.DYSQ));
        apply.setUserId(userSupport.getUserId());

        save(apply);

        // 打印申请 startProcessInstance
        printApplyProcessHandler.startProcessInstance(apply);

        // 塞入app审核列表主要信息
        PrintApplyRespVo vo = getVo( apply.getId() );
        activitiCoreInformationService.create( vo.getShisBusinessId(), vo.getShisBusinessType(), vo );
    }

    public PrintApply getWaitingPrintApply(String businessId, String BusinessType, String userId) {
        QueryWrapper<PrintApply> qw = new QueryWrapper<>();
        qw.lambda().eq(PrintApply::getBusinessId, businessId);
        qw.lambda().eq(PrintApply::getBusinessType, BusinessType);
        qw.lambda().eq(PrintApply::getUserId, userId);
        qw.lambda().eq(PrintApply::getApprovalStatus, ApprovalStatus.APPROVED.getStatus());
        qw.lambda().eq(PrintApply::getPrintFlag, CommonConst.FALSE);
        return getOne(qw);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void updatePrintFlag(String businessId, String BusinessType, String userId) {
        // update
        UpdateWrapper<PrintApply> uw = new UpdateWrapper<>();
        uw.lambda().set(PrintApply::getPrintFlag, CommonConst.TRUE);
        uw.lambda().eq(PrintApply::getBusinessId, businessId);
        uw.lambda().eq(PrintApply::getBusinessType, BusinessType);
        uw.lambda().eq(PrintApply::getApprovalStatus, ApprovalStatus.APPROVED.getStatus());
        uw.lambda().eq(PrintApply::getPrintFlag, CommonConst.FALSE);
        uw.lambda().eq(PrintApply::getUserId, userId);
        boolean success = update(uw);
    }

    public PrintApply getInApply(String businessId, String BusinessType, String userId) {
        QueryWrapper<PrintApply> qw = new QueryWrapper<>();
        qw.lambda().eq(PrintApply::getBusinessId, businessId);
        qw.lambda().eq(PrintApply::getBusinessType, BusinessType);
        qw.lambda().eq(PrintApply::getUserId, userId);
        qw.lambda().eq(PrintApply::getApprovalStatus, ApprovalStatus.PENDING_APPROVAL.getStatus());
        return getOne(qw);
    }

}
